package com.mililoan.common.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * Class Name: FileHelper Description: TODO 文件工具类
 * 
 * @author hjm
 *
 */
public class FileHelper {

	/**
	 * 
	 * Description: TODO 文件流转化为json
	 *
	 * @param inputStream
	 * @return
	 */
	public static String ConvertStream2Json(InputStream inputStream) {
		String jsonStr = "";
		// ByteArrayOutputStream相当于内存输出流
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		// 将输入流转移到内存输出流中
		try {
			while ((len = inputStream.read(buffer, 0, buffer.length)) != -1) {
				out.write(buffer, 0, len);
			}
			// 将内存流转换为字符串
			jsonStr = new String(out.toByteArray());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jsonStr;
	}

	/**
	 * 
	 * Description: TODO 文件转化为json
	 *
	 * @param fileName
	 * @return
	 */
	public static String ConvertCharStream2Json(String fileName) {
		File file = new File(fileName);
		Reader reader = null;
		StringBuffer jsonStr = new StringBuffer();
		try {
			// 一次读一个字符
			reader = new InputStreamReader(new FileInputStream(file));
			int tempchar;
			while ((tempchar = reader.read()) != -1) {
				// 对于windows下，\r\n这两个字符在一起时，表示一个换行。
				// 但如果这两个字符分开显示时，会换两次行。
				// 因此，屏蔽掉\r，或者屏蔽\n。否则，将会多出很多空行。
				if (((char) tempchar) != '\r') {
					jsonStr.append((char) tempchar);
				}
			}
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return jsonStr.toString();
	}

	/**
	 * 
	 *
	 * @param dir
	 *            目录
	 * @return
	 */
	public static List<File> getFileList(String dir) {
		List<File> fileList = new ArrayList<File>();

		File root = new File(dir);
		File[] files = root.listFiles();

		// 获取不到则读取项目路径
		if (null==files) {
			root = new File(getFilePath() + dir);
			files = root.listFiles();
		}

		if (null==files) {
			return null;
		}

		for (int i = 0; i < files.length; i++) {
			fileList.add(files[i]);
			// System.out.println("文件名"+i+":"+files[i]);
		}

		return fileList;
	}

	public static BufferedReader getFileStream(String filePath, String charset) {

		File file = new File(filePath);
		BufferedReader reader = null;
		InputStreamReader in = null;
		try {
			in = new InputStreamReader(new FileInputStream(file), charset);
			reader = new BufferedReader(in);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return reader;

	}

	/**
	 * 
	 * Description: TODO 判断该文件是否存在文件列表中
	 *
	 * @param fileList
	 *            文件列表
	 * @param fileName
	 *            文件名
	 * @return
	 */
	public static boolean checkExist(String fileName, List<File> fileList) {
		File file = null;
		for (int i = 0, length = fileList.size(); i < length; i++) {
			file = fileList.get(i);

			if (fileName.equals(file.getName())) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Description: 判断该文件是否存在
	 * 
	 * @param fileName
	 *            文件名
	 * @return String
	 */
	public static boolean checkExist(String fileName) {
		File file = new File(fileName);

		return file.exists();
	}

	/**
	 * Description： 删除文件
	 * 
	 * @return String
	 */
	public static void deleteFile(String fileName) {
		File file = new File(fileName);
		if (file.exists()) {
			file.delete();
		}
	}

	/**
	 * 获取系统当前路径
	 * 
	 * @return String
	 */
	public static String getFilePath() {
		String path = null;
		File directory = new File("");
		try {
			path = directory.getCanonicalPath();
		} catch (IOException e) {
			return path;
		}
		return path;
	}

	/**
	 * 
	 * Description: 写入文件
	 * 
	 * @param fileName
	 *            文件名
	 * @param str
	 *            数据集合
	 *
	 */
	public static void write2File(String fileName, String str, String charsetName) {

		OutputStreamWriter osw = null;
		try {
			osw = new OutputStreamWriter(new FileOutputStream(fileName, true), charsetName);
			osw.write(str);
			osw.flush();
			osw.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (osw != null) {
					osw.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 
	 * Description: 写入文件
	 * 
	 * @param fileName
	 *            文件名
	 * @param content
	 *
	 */
	public static void write2File(String fileName, String content) {
		FileWriter writer = null;
		try {
			// 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
			writer = new FileWriter(fileName, checkExist(fileName));
			writer.write(content);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (writer != null) {
					writer.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 复制单个文件
	 * 
	 * @param sourceFileName
	 *            待复制的文件名
	 * @param targetFileName
	 *            目标文件名
	 * @param overlay
	 *            如果目标文件存在，是否覆盖
	 * @return 如果复制成功返回true，否则返回false
	 */
	public static boolean copyFile(String sourceFileName, String targetFileName, boolean overlay) {
		File srcFile = new File(sourceFileName);
		// 判断源文件是否存在
		if (!srcFile.exists()) {
			return false;
		} else if (!srcFile.isFile()) {
			return false;
		}

		// 判断目标文件是否存在
		File destFile = new File(targetFileName);
		if (destFile.exists()) {
			// 如果目标文件存在并允许覆盖
			if (overlay) {
				// 删除已经存在的目标文件，无论目标文件是目录还是单个文件
				new File(targetFileName).delete();
			}
		} else {
			// 如果目标文件所在目录不存在，则创建目录
			if (!destFile.getParentFile().exists()) {
				// 目标文件所在目录不存在
				if (!destFile.getParentFile().mkdirs()) {
					// 复制文件失败：创建目标文件所在目录失败
					return false;
				}
			}
		}

		// 复制文件
		int byteread = 0; // 读取的字节数
		InputStream in = null;
		OutputStream out = null;

		try {
			in = new FileInputStream(srcFile);
			out = new FileOutputStream(destFile);
			byte[] buffer = new byte[1024];

			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
			return true;
		} catch (FileNotFoundException e) {
			return false;
		} catch (IOException e) {
			return false;
		} finally {
			try {
				if (out != null)
					out.close();
				if (in != null)
					in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 
	 * @Title: getUUID
	 * @Description: 创建UUID文件名
	 * @author YangChaofeng 2016年5月24日 上午10:13:11
	 * @return
	 */
	public static String getUUID() {
		Long uuid = UUID.randomUUID().getMostSignificantBits();
		if (uuid < 0) {
			uuid = -1 * uuid;
		}
		return uuid.toString();
	}
	
	/**
	 * 下载文件时指定下载名
	 * 
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse
	 * @param filePath
	 *            文件全路径
	 * @param fileName
	 *            指定客户端下载时显示的文件名
	 * @throws IOException
	 */
	public static void downloadFile(HttpServletRequest request,
			HttpServletResponse response, String filePath, String fileName)
			throws IOException {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;

		bis = new BufferedInputStream(new FileInputStream(filePath));
		bos = new BufferedOutputStream(response.getOutputStream());

		long fileLength = new File(filePath).length();

		response.setCharacterEncoding("UTF-8");
		response.setContentType("multipart/form-data");
		// 解决各浏览器的中文乱码问题
		String userAgent = request.getHeader("User-Agent");
		// fileName.getBytes("UTF-8")处理safari的乱码问题
		byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes()
				: fileName.getBytes("UTF-8"); 
		// 各浏览器基本都支持ISO编码
		fileName = new String(bytes, "ISO-8859-1");
		response.setHeader("Content-disposition",
				String.format("attachment; filename=\"%s\"", fileName));

		response.setHeader("Content-Length", String.valueOf(fileLength));
		byte[] buff = new byte[2048];
		int bytesRead;
		while ((bytesRead = bis.read(buff)) != -1) {
			bos.write(buff, 0, bytesRead);
		}
		bis.close();
		bos.close();
	}
}
